// Configurar el puerto serie
// http://www.linuxquestions.org/questions/programming-9/setup-serial-port-at-1200b-7bits-even-parity-and-1-top-bit-494375/


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>   // Error number definitions 
#include <termios.h> // POSIX terminal control definitions 
#include "envio_mensaje.cpp"
#include "calculo_crc.cpp"

// Definiciones de Longitud de strings
#define BYTES_BASURA 20
#define Long_direccion 7
#define Long_texto 32
#define Long_CRC 1
#define Longitud_mensaje BYTES_BASURA+Long_direccion+Long_texto+Long_CRC

//  PROTOTIPOS
int open_port(char *argv[]);
bool envio_mensaje(char * mensaje, int serialfd);
void concatenar_string ( char * destination, char * source, int longitud1, int longitud2 );
bool parse_args( int argc, char* argv[]);
int calc_crc(int crc, int byte);
int hextoi(char caracter);


char basura[BYTES_BASURA] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
// El receptor busca el caracter de inicio de mensaje, luego los bytes 1 a 6 de la dirección, ignorando el 1(familia) y el 7(CRC)


char direccion[7];

int main( int argc, char* argv[] )
{
        if( !parse_args(argc,argv) )
        return 1;  
	
// Generando el comando para abrir el puerto Serie

  char cmd1[40];
  char cmd2[20];
  char cmd3[16];

  strcpy (cmd1,"stty -F ");
  strcpy (cmd2,argv[1]);
  strcpy (cmd3," 1200 cs8 cstopb");
  strncat (cmd1, cmd2, 12);
  strncat (cmd1, cmd3, 16);

  int serialfd;
  system(cmd1);  //Ejecuta el comando que configura el puerto serie.
  serialfd = open_port(argv);  // Abre el puerto serie

// Puerto serie abierto y configurado



// Obtener direccion del display (argumento 2)

    char dir1[14]="";

   // printf("\nDireccion: %s \n",argv[2]);
    strcpy (dir1,argv[2]);
    int aux_dir1=0;
    int aux_dir2=1;
    char aux_dir3=0;

	printf("\n \n \n");

direccion[0]=0x60;

for(aux_dir1=0;aux_dir1<14;aux_dir1++)
	{

	aux_dir3=hextoi(dir1[aux_dir1])*16;

	aux_dir1++;
	aux_dir3=aux_dir3+hextoi(dir1[aux_dir1]);

	direccion[aux_dir2]=aux_dir3;

	aux_dir2++;
	aux_dir3=0;
	}

// Direccion configurada //////////////////////




    char texto[Long_texto]="";
    char mensaje[Longitud_mensaje]="";

    printf( "Escriba el mensaje:\n" );

    printf("\nString: %s \n",argv[3]);

    strcpy (texto,argv[3]);

//    scanf("%32[^\n]", texto);   //  similar a "gets( texto );" pero sin error, con un maximo de 32 caracteres    
    printf("\n TEXTO: %s \n", texto);

// Para terminar rellenar el espacio faltante del display   
    int  caracteres;
    caracteres = strlen(texto);
    strncat (texto,"                                                     ",35-caracteres);

    concatenar_string(mensaje,basura,0,BYTES_BASURA); 
    concatenar_string(mensaje,direccion,BYTES_BASURA,Long_direccion);
    concatenar_string(mensaje,texto,BYTES_BASURA+Long_direccion,Long_texto); 
    
    char crc = 0;
    int byteN = 0;
    char serial[7];
    

     byteN=0;
     for (byteN=0;byteN<(Longitud_mensaje-BYTES_BASURA-Long_CRC);byteN++)
      {
      crc = calc_crc(crc,mensaje[byteN+BYTES_BASURA]);
      }


    
    // Agrego el byte del CRC
    concatenar_string(mensaje,texto,Longitud_mensaje,1); 
    
    if(!envio_mensaje(mensaje, serialfd))
        return 1;    


usleep(600000);
//sleep(1);
return 0;
}

bool parse_args( int argc, char* argv[] )
{
	char aux_direccion[14]="";

    if( argc!=4 )
    {
     
	printf("\nCantidad de argumentos: %i \n",argc);
	printf("\nError: Cantidad de argumentos inválida.\n");
        printf("\nForma de uso: a.out <dispositivo-serie> <direccion_display> \"Mensaje\" \n");
	return false;
    }


	if (strlen(argv[2])!=12)
		{
	        printf("\nLa direccion tiene que tener el formato que muestra el display \n");
		return false;
		}

	strcpy (aux_direccion,argv[2]);
	
	int aux;
	for(aux=0;aux<12;aux++)
	{
		if(aux_direccion[aux]!='0' && aux_direccion[aux]!='1' && aux_direccion[aux]!='2' && aux_direccion[aux]!='3' && aux_direccion[aux]!='4' && aux_direccion[aux]!='5' && aux_direccion[aux]!='6' && aux_direccion[aux]!='7' && aux_direccion[aux]!='8' && aux_direccion[aux]!='9' && aux_direccion[aux]!='a' && aux_direccion[aux]!='b' && aux_direccion[aux]!='c' && aux_direccion[aux]!='d' && aux_direccion[aux]!='e' && aux_direccion[aux]!='f' && aux_direccion[aux]!='A' && aux_direccion[aux]!='B' && aux_direccion[aux]!='C' && aux_direccion[aux]!='D' && aux_direccion[aux]!='E' && aux_direccion[aux]!='F')
		{
        	printf("\nLa direccion tiene que tener el formato que muestra el display \n");
		return false;
		}
	}



     return true;
}


void concatenar_string (char * destination,char * source,int longitud1, int longitud2)
{
  unsigned int i;
  for (i=0;i<longitud2;i++)
  {
    destination[longitud1+i]=source[i];
  }
}


int hextoi(char caracter)
{
switch (caracter)
	{
	case '0':
	return 0;
	break;

	case '1':
	return 1;
	break;

	case '2':
	return 2;
	break;

	case '3':
	return 3;
	break;

	case '4':
	return 4;
	break;

	case '5':
	return 5;
	break;

	case '6':
	return 6;
	break;

	case '7':
	return 7;
	break;

	case '8':
	return 8;
	break;

	case '9':
	return 9;
	break;

	case 'A':
	return 10;
	break;

	case 'a':
	return 10;
	break;

	case 'B':
	return 11;
	break;

	case 'b':
	return 11;
	break;

	case 'C':
	return 12;
	break;

	case 'c':
	return 12;
	break;

	case 'D':
	return 13;
	break;

	case 'd':
	return 13;
	break;

	case 'E':
	return 14;
	break;

	case 'e':
	return 14;
	break;

	case 'F':
	return 15;
	break;

	case 'f':
	return 15;
	break;

	default:
	return 16;

	}

}




